#ifndef __VIDEOCODECSTREAM_H__
#define __VIDEOCODECSTREAM_H__

#include "MultiThreadEventManager.h"
#include "streamforchannel.h"

///////////////////////////////////////////////////////
//	Contain pthread
#if defined(WIN32)
#include "pthread.h"
#else
#include <pthread.h>
#endif

extern "C"{//
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavdevice/avdevice.h"
}

#include "streamforchannel.h"
#include <stdlib.h>
#include <deque>

class CCodecManager;

/////////////////////////////////////////Class IDs////////////////////////////////////////////

#define CLASS_ID_CVIDEOCODECSTREAM 0x10000
#define CLASS_ID_CVIDEOSTREAMENCODER 0x10100
#define CLASS_ID_CVIDEOSTREAMDECODER 0x10200
#define CLASS_ID_CVIDEOFILEENCODER 0x10101
#define CLASS_ID_CVIDEOFILEDECODER 0x10201

/////////////////////////////////////////Raw Class////////////////////////////////////////////

class CVideoCodecStream:
	public CStreamBase,public CMultiThreadEvent
{
public:
	CVideoCodecStream(void);
	virtual ~CVideoCodecStream(void);
	virtual unsigned long GetClassID(){return CLASS_ID_CVIDEOCODECSTREAM;};
	static unsigned long CLASS_ID(){return CLASS_ID_CVIDEOCODECSTREAM;};
	friend class CCodecManager;
	virtual void OnEvent(CMultiThreadEventManager* pMgr){};
protected:
	CMultiThreadEventManager* p_event_manager;
};


/////////////////////////////////////////Proxy Classes////////////////////////////////////////////

class CVideoStreamEncoder
{
public:
	CVideoStreamEncoder(CVideoCodecStream* pS){pVideoStream=pS;};
	virtual ~CVideoStreamEncoder(){};
	virtual unsigned long GetClassID(){return CLASS_ID_CVIDEOSTREAMENCODER;};
	static unsigned long CLASS_ID(){return CLASS_ID_CVIDEOSTREAMENCODER;};
	CVideoCodecStream* getVideoCodecStream(){return pVideoStream;};
	friend class CCodecManager;
protected:
	CVideoStreamEncoder(){};
	CVideoStreamEncoder(CVideoStreamEncoder&){};
	CVideoCodecStream* pVideoStream;
	CMultiThreadEventManager* p_event_manager;
};

class CVideoFileEncoder:
	public CVideoStreamEncoder
{
public:
	CVideoFileEncoder(CVideoCodecStream* pS){pVideoStream=pS;};
	virtual ~CVideoFileEncoder(){};
	virtual unsigned long GetClassID(){return CLASS_ID_CVIDEOFILEENCODER;};
	static unsigned long CLASS_ID(){return CLASS_ID_CVIDEOFILEENCODER;};
	friend class CCodecManager;
protected:
	CVideoFileEncoder(){};
	CVideoFileEncoder(CVideoFileEncoder&){};
	CMultiThreadEventManager* p_event_manager;
};

class CVideoStreamDecoder
{
public:
	CVideoStreamDecoder(CVideoCodecStream* pS){pVideoStream=pS;};
	virtual ~CVideoStreamDecoder(){};
	virtual unsigned long GetClassID(){return CLASS_ID_CVIDEOSTREAMDECODER;};
	static unsigned long CLASS_ID(){return CLASS_ID_CVIDEOSTREAMDECODER;};
	CVideoCodecStream* getVideoCodecStream(){return pVideoStream;};
	friend class CCodecManager;
protected:
	CVideoStreamDecoder(){};
	CVideoStreamDecoder(CVideoStreamDecoder&){};
	CVideoCodecStream* pVideoStream;
	CMultiThreadEventManager* p_event_manager;
};


class CVideoFileDecoder:
	public CVideoStreamDecoder
{
public:
	CVideoFileDecoder(CVideoCodecStream* pS){pVideoStream=pS;};
	virtual ~CVideoFileDecoder(){};
	virtual unsigned long GetClassID(){return CLASS_ID_CVIDEOFILEDECODER;};
	static unsigned long CLASS_ID(){return CLASS_ID_CVIDEOFILEDECODER;};
	friend class CCodecManager;
protected:
	CVideoFileDecoder(){};
	CVideoFileDecoder(CVideoFileDecoder&){};
	CMultiThreadEventManager* p_event_manager;
};

#endif